package com.dylan.magic.guava.util;

import com.dylan.magic.common.util.ThreadPoolUtil;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;

import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * @author : ankang
 * @date : 2020/3/1 19:09
 * @Description :
 */
public class GuavaAsyncCacheBuilder<K, V> {
    private CacheBuilder<K, V> cacheBuilder;

    public static GuavaAsyncCacheBuilder<Object, Object> builder() {
        GuavaAsyncCacheBuilder<Object, Object> builder = new GuavaAsyncCacheBuilder<>();
        builder.cacheBuilder = CacheBuilder.newBuilder();
        return builder;
    }

    public GuavaAsyncCacheBuilder<K, V> refreshAfterWrite(Duration duration) {
        cacheBuilder.refreshAfterWrite(duration);
        return this;
    }

    public GuavaAsyncCacheBuilder<K, V> refreshAfterWrite(long duration, TimeUnit unit) {
        cacheBuilder.refreshAfterWrite(duration, unit);
        return this;
    }

    public GuavaAsyncCacheBuilder<K, V> maximumSize(long maximumSize) {
        cacheBuilder.maximumSize(maximumSize);
        return this;
    }

    public GuavaAsyncCacheBuilder<K, V> removalListener(RemovalListener<? super K, ? super V> listener) {
        cacheBuilder.removalListener(listener);
        return this;
    }

    public <K1 extends K, V1 extends V> LoadingCache<K1, V1> build(Function<K1, V1> function) {
        return cacheBuilder.build(GuavaCacheUtil.buildAsyncCacheLoader(function, ThreadPoolUtil.getExecutorService()));
    }
}
